package com.servertest1;

import java.util.Arrays;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import android.os.Handler;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;
import android.widget.PopupWindow;
import android.view.ViewGroup.LayoutParams;

//TODO: Make your turn and their turn disappear if they empty (or just put a string
//saying they are empty)

//TODO: When you click on a game twice quickly, the client sends get_game to server
//twice.



public class Menu extends Activity implements OnClickListener
{
	public static final int MILLI_SEC_BETWEEN_POLLS = 15000;
	public static final int ELEMENTS_PER_GAME_PACKAGE = 4;
	//private Button btnNewGame;
	private ImageButton btnNewGame;
	private ImageButton logout;
	private ImageButton profile;
	private LinearLayout your_turn_games_list = null;
	private LinearLayout their_turn_games_list = null;
	private TextView searching = null;

	private DatabaseHelper helper;
	private Client client;
	private Handler m_Handler;

	private int gamePosition;
	private String opponent;

	// Create list of current games
	ArrayList<Game>  your_turn_games = new ArrayList<Game>();
	ArrayList<Game> their_turn_games = new ArrayList<Game>();

	String search_text = "Searching for game...";

	// Bundle to be sent to Board class
	String[] score_screen_data = new String[11];
	String[] profile_screen_data = new String[5];

	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		// TODO: Add symbol if searching for game
		super.onCreate(savedInstanceState);
		setContentView(R.layout.menu);

		// Set up buttons
		btnNewGame = (ImageButton) findViewById(R.id.createNewGame);
		btnNewGame.setOnClickListener(this);

		logout = (ImageButton) findViewById(R.id.logout_btn);
		logout.setOnClickListener(this);
		
		profile = (ImageButton) findViewById(R.id.profile_btn);
		profile.setOnClickListener(this);

		// Set up ListViews
		your_turn_games_list =  (LinearLayout) findViewById(R.id.your_turn_games_list);
		their_turn_games_list = (LinearLayout) findViewById(R.id.their_turn_games_list);

		// Set up Searching text
		searching = (TextView) findViewById(R.id.searching);

		// Retrieve current games
		Bundle extras = getIntent().getExtras();
		String[] gameData = extras.getStringArray("gameData");

		refreshMenu(gameData);

		m_Handler = new Handler();
		refreshChecker.run();
	}

	private void displayCurrentGames()
	{
		your_turn_games_list.removeAllViews();
		their_turn_games_list.removeAllViews();
		
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		for (int current = 0; current < your_turn_games.size(); current++) {
			
			final View view;
			if(current == 0 && current == your_turn_games.size() - 1){
				view = inflater.inflate(R.layout.listitem_only, your_turn_games_list, false);
			}
			else if(current == 0){
				view = inflater.inflate(R.layout.listitem_top, your_turn_games_list, false);
			}
			else if(current == your_turn_games.size() - 1){
				view = inflater.inflate(R.layout.listitem_bot, your_turn_games_list, false);
			}
			else{
				view = inflater.inflate(R.layout.listitem, your_turn_games_list, false);
			}
			
			Game user = your_turn_games.get(current);
			if (user != null) 
			{
				TextView opponent = (TextView) view.findViewById(R.id.opponent);
				if (opponent != null) 
				{
					opponent.setText("Play against: " + user.opponent);
				}
			}

			// Scale logo
			ImageView logo = (ImageView) view.findViewById(R.id.avatar);
			ImageScaler is = new ImageScaler();
			is.scaleImage(logo, 50);

			//initialize the view
			view.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// Grab the game id from array of games
					int index = your_turn_games_list.indexOfChild(v) / 2;
					System.out.println("index:" + index);
					int needsOk = your_turn_games.get(index).needsOk;


					if(needsOk == 1) {
						LayoutInflater layoutInflater 
						= (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);  
						View popupView = layoutInflater.inflate(R.layout.game_accept_popup, null);  
						final PopupWindow popupWindow = new PopupWindow(
								popupView, 
								LayoutParams.WRAP_CONTENT,  
								LayoutParams.WRAP_CONTENT);  
						Button btnDismiss = (Button)popupView.findViewById(R.id.decline_popup);
						btnDismiss.setOnClickListener(new Button.OnClickListener(){

							public void onClick(View v) {
								int index = your_turn_games_list.indexOfChild(v) / 2;
								int game_id = Integer.parseInt(your_turn_games.get(index).gameId);
								String[] cmd = new String[2];
								cmd[0] = "deny_game";
								cmd[1] = Integer.toString(game_id);
								new deny_game().execute(cmd);
								popupWindow.dismiss();
							}});
						
						Button btnAccept = (Button)popupView.findViewById(R.id.accept_popup);
						btnAccept.setOnClickListener(new Button.OnClickListener(){
							public void onClick(View v) {
								int index = your_turn_games_list.indexOfChild(v) / 2;
								int game_id = Integer.parseInt(your_turn_games.get(index).gameId);
								// Create command for server
								String[] cmd = new String[3];
								cmd[0] = "score_screen";
								cmd[1] = Integer.toString(game_id);
								cmd[2] = "update";
								
								// Execute command on server
								new Get_Game().execute(cmd);
								popupWindow.dismiss();
							}
						});

						popupWindow.showAsDropDown(view, 350, -300);


					}
					else{
						int game_id = Integer.parseInt(your_turn_games.get(index).gameId);
						opponent = your_turn_games.get(index).opponent;
						// Create command for server
						String[] cmd = new String[3];
						cmd[0] = "score_screen";
						cmd[1] = Integer.toString(game_id);
						cmd[2] = "no_update";
	
						// Execute command on server
						new Get_Game().execute(cmd);
					}
				}
			});

			your_turn_games_list.addView(view);

			//divider
			if (current < your_turn_games.size() - 1) {
				inflater.inflate(R.layout.line, your_turn_games_list);
			}

		}
		
		inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		for (int current = 0; current < their_turn_games.size(); current++) {
			final View view;
			if(current == 0 && current == their_turn_games.size() - 1){
				view = inflater.inflate(R.layout.listitem_only, their_turn_games_list, false);
			}
			else if(current == 0){
				view = inflater.inflate(R.layout.listitem_top, their_turn_games_list, false);
			}
			else if(current == their_turn_games.size() - 1){
				view = inflater.inflate(R.layout.listitem_bot, their_turn_games_list, false);
			}
			else{
				view = inflater.inflate(R.layout.listitem, their_turn_games_list, false);
			}
			
			Game user = their_turn_games.get(current);
			   
			if (user != null) 
			{
				TextView opponent = (TextView) view.findViewById(R.id.opponent);
				if (opponent != null) 
				{
					opponent.setText("Play against: " + user.opponent);
				}
			}

			// Scale logo
			ImageView logo = (ImageView) view.findViewById(R.id.avatar);
			ImageScaler is = new ImageScaler();
			is.scaleImage(logo, 50);

			//initialize the view
			view.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// Grab the game id from array of games
					int index = their_turn_games_list.indexOfChild(v) / 2;
					int needsOk = their_turn_games.get(index).needsOk;
					
					
					
					if(needsOk == 1) {
						LayoutInflater layoutInflater 
						= (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);  
						View popupView = layoutInflater.inflate(R.layout.game_accept_popup, null);  
						final PopupWindow popupWindow = new PopupWindow(
								popupView, 
								LayoutParams.WRAP_CONTENT,  
								LayoutParams.WRAP_CONTENT);  

						Button btnDismiss = (Button)popupView.findViewById(R.id.decline_popup);
						btnDismiss.setOnClickListener(new Button.OnClickListener(){

							public void onClick(View v) {
								int index = their_turn_games_list.indexOfChild(v) / 2;
								int game_id = Integer.parseInt(their_turn_games.get(index).gameId);
								String[] cmd = new String[2];
								cmd[0] = "deny_game";
								cmd[1] = Integer.toString(game_id);
								new deny_game().execute(cmd);
								popupWindow.dismiss();
							}});
						
						Button btnAccept = (Button)popupView.findViewById(R.id.accept_popup);
						btnAccept.setOnClickListener(new Button.OnClickListener(){
							public void onClick(View v) {
								int index = their_turn_games_list.indexOfChild(v) / 2;
								int game_id = Integer.parseInt(their_turn_games.get(index).gameId);
								opponent = their_turn_games.get(index).opponent;
								// Create command for server
								String[] cmd = new String[3];
								cmd[0] = "score_screen";
								cmd[1] = Integer.toString(game_id);
								cmd[2] = "update";
			
								// Execute command on server
								new Get_Game().execute(cmd);
								popupWindow.dismiss();
							}
						});

						popupWindow.showAsDropDown(view, 350, -300);


					}
					
					else{
						int game_id = Integer.parseInt(their_turn_games.get(index).gameId);
						opponent = their_turn_games.get(index).opponent;
						// Create command for server
						String[] cmd = new String[3];
						cmd[0] = "score_screen";
						cmd[1] = Integer.toString(game_id);
						cmd[2] = "no_update";
	
						// Execute command on server
						new Get_Game().execute(cmd);
					}
				}
			});

			their_turn_games_list.addView(view);

			//divider
			if (current < their_turn_games.size() - 1) {
				inflater.inflate(R.layout.line, their_turn_games_list);
			}
		}
	}

	private void refreshMenu(String[] gameData) {
		setCurrentGames(gameData, your_turn_games, their_turn_games);
		displayCurrentGames();
	}

	private void setCurrentGames(String[] gameData, ArrayList<Game> your_turn_games, ArrayList<Game> their_turn_games)
	{
		System.out.println("STARTING SET CURRENT GAMES");
		for(int i = 0; i < gameData.length; i++){
			System.out.println(gameData[i]);
		}
		System.out.println("\n\n\n");
		your_turn_games.clear();
		their_turn_games.clear();
		for (int i = 1; i < gameData.length-1; i += ELEMENTS_PER_GAME_PACKAGE)
		{
			if (gameData[i+2].equals("your_turn"))
			{
				Game game = new Game(gameData[i], gameData[i+1], true, Integer.parseInt(gameData[i+3]));
				your_turn_games.add(game);
			}
			else if (gameData[i+2].equals("their_turn"))
			{
				Game game = new Game(gameData[i], gameData[i+1], false, Integer.parseInt(gameData[i+3]));
				their_turn_games.add(game);
			}
		}

		if (gameData[gameData.length-1].equals("is_searching"))
		{
			searching.setText(search_text);
		}
		else if (gameData[gameData.length-1].equals("not_searching"))
		{
			searching.setText("");
		}
		else
		{
			searching.setText("Something else..." + gameData[gameData.length-1]);
			//searching.setText(gameData[gameData.length-1] + "...#odoylerulz");
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (helper != null) {
			helper.close();
		}
		m_Handler.removeCallbacks(refreshChecker);
		this.client.close();
	}


	@Override
	public void onRestart(){
		super.onRestart();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);

		refreshChecker = new Runnable() {
			public void run() {
				sendPoll();
				m_Handler.postDelayed(refreshChecker, MILLI_SEC_BETWEEN_POLLS);
			}
		};

		refreshChecker.run();
	}

	public void onClick(View v) 
	{
		switch (v.getId())
		{
		case R.id.createNewGame:
			m_Handler.removeCallbacks(refreshChecker);
			Intent myIntent = new Intent(Menu.this, NewGame.class);
			Menu.this.startActivityForResult(myIntent, 0);
			break;
		case R.id.logout_btn:
			m_Handler.removeCallbacks(refreshChecker);
			helper = new DatabaseHelper(this);
			helper.deleteAll();
			Intent myIntent2 = new Intent(Menu.this, Login.class);
			Menu.this.startActivity(myIntent2);
			finish();
			break;
		case R.id.profile_btn:
			helper = new DatabaseHelper(this);
			String[] cmd = new String[2];
	    	cmd[0] = "profile_screen";
	    	cmd[1] = helper.getUser();
	    	helper.close();

	    	  // Execute command on server
	    	 new Get_Profile().execute(cmd);
		default:
			break;
		}
	}

	private class Game 
	{
		public String opponent;
		public String gameId;
		public int needsOk;
		public boolean yourTurn;

		public Game(String gameId, String opponent, boolean yourTurn, int hasAccepted) 
		{
			this.gameId = gameId;
			this.opponent = opponent;
			this.yourTurn = yourTurn;
			this.needsOk = hasAccepted;
		}
	}

	private void sendPoll() {
		helper = new DatabaseHelper(this);
		String username = helper.getUser();
		helper.close();

		String[] cmd = new String[2];
		cmd[0] = "fetch_games";
		cmd[1] = username;
		new poll_server().execute(cmd);
	}

	Runnable refreshChecker = new Runnable() {
		public void run() {
			try{
				sendPoll();
				m_Handler.postDelayed(refreshChecker, MILLI_SEC_BETWEEN_POLLS);
			}
			catch(Exception e){
				System.out.println("oops");
			}
		}
	};

	

	private class deny_game extends AsyncTask<String, Void, String[]> {
		protected String[] doInBackground(String... cmd) {
			if (client == null) {
				client = new Client();
			}
			
			client.connect();
			client.sendData(cmd);
			String[] result = client.recieveData();
			client.close();
			
			return result;
		}
		
		protected void onPostExecute(String[] result) {
			if(result[0].equals("success_deny_game")) {
				sendPoll();
			}
			else {
				System.out.println("The Result:" + result[0]);
				System.err.println("An error has occured (onPostExecute)");
				finish();
			}
		}
	}
	
	private class fetch_games extends AsyncTask<String, Void, String[]> {
		protected String[] doInBackground(String... cmd) {
			if (client == null) {
				client = new Client();
			}

			client.connect();
			client.sendData(cmd);
			String[] result = client.recieveData();
			client.close();

			return result;
		}

		protected void onPostExecute(String[] result) {
			if(result[0].equals("success")) {
				refreshMenu(result);
			}
			else {
				System.out.println("The Result:" + result[0]);
				System.err.println("An error has occured (game refresh)");
				finish();
			}
		}
	}

	private class Get_Game extends AsyncTask<String, Void, String[]>
	{

		protected String[] doInBackground(String... cmd)
		{		
			m_Handler.removeCallbacks(refreshChecker);
			// Connect to server
			if (client == null)
			{
				client = new Client();
			}

			client.connect();
			client.sendData(cmd);
			String[] result = client.recieveData();
			client.close();

			return result;
		}

		protected void onPostExecute(String[] result)
		{	

			if (result[0].equals("success_score_screen"))
			{
				for (int i = 1; i < result.length; i++)
				{
					score_screen_data[i-1] = result[i];
				}
				Intent myIntent = new Intent(Menu.this, ScoreScreen.class);
				//myIntent.putExtra("position", gamePosition);
				//myIntent.putExtra("your_turn_games", your_turn_games);
				myIntent.putExtra("score_screen_data", score_screen_data);
				Menu.this.startActivityForResult(myIntent, 1);
				//Intent myIntent = new Intent(Menu.this, Board.class);
				//myIntent.putExtra("board_data", board_bundle);
				//startActivity(myIntent);
			}
			else
			{
				System.out.println("Server's message not success: " + result[0]);
			}
		}
	}

	private class Get_Profile extends AsyncTask<String, Void, String[]>
	{
		
		protected String[] doInBackground(String... cmd)
		{			
			// Connect to server
			if (client == null)
			{
				client = new Client();
			}

			client.connect();
			client.sendData(cmd);
			String[] result = client.recieveData();
			client.close();

			return result;
		}

		protected void onPostExecute(String[] result)
		{	

			if (result[0].equals("success_profile_screen"))
			{
				for (int i = 1; i < result.length; i++)
				{
					profile_screen_data[i-1] = result[i];
				}
				m_Handler.removeCallbacks(refreshChecker);
				Intent myIntent = new Intent(Menu.this, ProfileScreen.class);
				myIntent.putExtra("profile_screen_data", profile_screen_data);
				Menu.this.startActivityForResult(myIntent, 2);
			}
			else
			{
				System.out.println("Server's message not success: " + result[0]);
			}
		}
	}
	
	private class poll_server extends AsyncTask<String, Void, String[]> {
		protected String[] doInBackground(String... cmd) {

			if(client == null) {
				client = new Client();
			}
			client.connect();
			client.sendData(cmd);
			String[] result = client.recieveData();
			client.close();

			return result;

		}

		protected void onPostExecute(String[] result) {
			setCurrentGames(result, your_turn_games, their_turn_games);
			displayCurrentGames();
		}
	}

}
